package com.laiketui.core.utils.okhttp;

import com.alibaba.fastjson.JSON;
import com.laiketui.core.exception.LaiKeAPIException;
import com.laiketui.core.lktconst.ErrorCode;
import com.laiketui.core.lktconst.GloabConst;
import okhttp3.*;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;

@Component
public class OkHttpUtils {

    private static final Logger logger = LoggerFactory.getLogger(OkHttpUtils.class);

    @Autowired
    private OkHttpClient okHttpClient;


    private String addHandle(String val){
        if(val !=null && !"".equals(val)){
            return val.replaceAll("\\+","%2B");
        }
        return val;
    }


    public void downloadFile(String methodType, String url, Map<String, String[]> queries, HttpServletResponse lastresponse) throws Exception {
        FormBody.Builder builder = new FormBody.Builder();
        //添加参数
        if (queries != null && queries.keySet().size() > 0) {
            for (String key : queries.keySet()) {
                String[] vals = queries.get(key);
                if (vals != null && vals.length > 0) {
                    for (String val : vals) {
                        builder.add(key, addHandle(val));
                    }
                }
            }
        }
        Request request = new Request.Builder()
                .url(url)
                .post(builder.build())
                .build();
        Response response = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            response = okHttpClient.newCall(request).execute();
            try {
                inputStream = response.body().byteStream();
                outputStream = lastresponse.getOutputStream();
                int len;
                byte[] buff = new byte[1024];
                while ((len = inputStream.read(buff)) != -1) {
                    outputStream.write(buff, 0, len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            logger.error("okhttp3 post 错误 >> ex = {}", ExceptionUtils.getStackTrace(e));
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * dispatch
     *
     * @param methodType
     * @param url
     * @param queries
     * @return
     */
    public String dispatch(String methodType, String url, Map queries) {
        try {
            switch (methodType) {
                case GloabConst.RequestMethod.GET:
                    return get(url, queries);
                default:
                    return post(url, queries);
            }
        } catch (Exception e){
            throw new LaiKeAPIException(ErrorCode.ContainerErrorCode.GW_API_FAIL,e.getMessage());
        }
    }

    /**
     * 文件上传
     *
     * @param file
     * @param filePath
     */
    private File upload(MultipartFile file, String filePath) {
        String fileName = file.getOriginalFilename();
        logger.debug("本地上传图片中 路径:{}", filePath + fileName);
        File dest = new File(filePath + fileName);
        try {
            file.transferTo(dest);
            logger.debug("图片本地上传成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return dest;
    }

    /**
     * @param files
     * @param image
     * @return
     */
    public String sendRequestUpload(MultipartFile[] files, MultipartFile image, String url, Map<String, String[]> queries) {
        try {
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = requestAttributes.getRequest();
//            boolean isFileUpload = ServletFileUpload.isMultipartContent(request);

            String responseBody = "";
            MultipartBody.Builder builder = new MultipartBody.Builder();
            builder.setType(MultipartBody.FORM);
            //添加参数
            if (queries != null && queries.keySet().size() > 0) {
                for (String key : queries.keySet()) {
                    String[] vals = queries.get(key);
                    if (vals != null && vals.length > 0) {
                        for (String val : vals) {
                            builder.addFormDataPart(key, addHandle(val));
                        }
                    }
                }
            }

            //多文件
            if(files != null){
                for (MultipartFile file : files) {
                    // image 这个
                    //取到文件名
                    String fileName = file.getOriginalFilename();
                    builder.addFormDataPart("image", fileName, RequestBody.create(file.getBytes(),MediaType.parse("multipart/form-data;charset=utf-8")));
                }
            }

            //单文件
            if( image != null ){
                builder.addFormDataPart("image", image.getOriginalFilename() , RequestBody.create(image.getBytes(),MediaType.parse("multipart/form-data;charset=utf-8")));
            }

            Request request1 = new Request.Builder().url(url)
                    .post(builder.build()).build();

            try {
                Call call = okHttpClient.newCall(request1);
                responseBody = Objects.requireNonNull(call.execute().body()).string();
                logger.info("文件上传返回结果：{}", JSON.toJSONString(responseBody));
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("okhttp3 post 错误 >> 异常 =  ", e);
            }
            return responseBody;
        } catch (Exception e) {
            logger.debug("网关处理图片上传异常",e);
            return null;
        }
    }


    /**
     * get
     *
     * @param url     请求的url
     * @param queries 请求的参数，在浏览器？后面的数据，没有可以传null
     * @return
     */
    public String get(String url, Map<String, String> queries) throws Exception {
        String responseBody = "";
        StringBuffer sb = new StringBuffer(url);
        if (queries != null && queries.keySet().size() > 0) {
            boolean firstFlag = true;
            Iterator iterator = queries.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry<String, String>) iterator.next();
                String key = (String) entry.getKey();
                String val = (String) entry.getValue();
                if (firstFlag) {
                    sb.append("?" + key + "=" + addHandle(val));
                    firstFlag = false;
                } else {
                    sb.append("&" + key + "=" + addHandle(val));
                }
            }
        }
        Request request = new Request.Builder()
                .url(sb.toString())
                .build();
        Response response = null;
        try {
            response = okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            logger.error("okhttp3 put 错误 >> ex = {}", ExceptionUtils.getStackTrace(e));
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return responseBody;
    }

    /**
     * post
     *
     * @param url     请求的url
     * @param queries post form 提交的参数
     * @return
     */
    public String post(String url, Map<String, String[]> queries) throws IOException {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest orgRequest = requestAttributes.getRequest();

        String responseBody = "";
        InputStream inputStream = null;
        InputStreamReader reader = null;
        Response response = null;
        BufferedReader br = null;
        try {
            inputStream = orgRequest.getInputStream();
            reader = new InputStreamReader(inputStream);
            br = new BufferedReader(reader);
            String line;
            StringBuilder sb = new StringBuilder( );
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

            FormBody.Builder builder = new FormBody.Builder();
            //sb是不是也要addHandle操作
            builder.add("weChat_xml", sb.toString());

            //添加参数
            if (queries != null && queries.keySet().size() > 0) {
                for (String key : queries.keySet()) {
                    String[] vals = queries.get(key);
                    if (vals != null && vals.length > 0) {
                        for (String val : vals) {
                            builder.add(key, addHandle(val));
                        }
                    }
                }
            }

            Request request = new Request.Builder()
                    .url(url)
                    .post(builder.build())
                    .build();
            response = okHttpClient.newCall(request).execute();
            return response.body().string();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("okhttp3 post 错误 >> ex = {}", ExceptionUtils.getStackTrace(e));
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (reader != null) {
                reader.close();
            }
            if (br != null) {
                br.close();
            }
            if (response != null) {
                response.close();
            }
        }
        return responseBody;
    }

    /**
     * get
     *
     * @param url     请求的url
     * @param queries 请求的参数，在浏览器？后面的数据，没有可以传null
     * @return
     */
    public String getForHeader(String url, Map<String, String> queries) {
        String responseBody = "";
        StringBuffer sb = new StringBuffer(url);
        if (queries != null && queries.keySet().size() > 0) {
            boolean firstFlag = true;
            Iterator iterator = queries.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry<String, String>) iterator.next();
                if (firstFlag) {
                    sb.append("?" + entry.getKey() + "=" + entry.getValue());
                    firstFlag = false;
                } else {
                    sb.append("&" + entry.getKey() + "=" + entry.getValue());
                }
            }
        }
        Request request = new Request.Builder()
                .addHeader("key", "value")
                .url(sb.toString())
                .build();
        Response response = null;
        try {
            response = okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            logger.error("okhttp3 put 错误 >> ex = {}", ExceptionUtils.getStackTrace(e));
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return responseBody;
    }

    /**
     * Post请求发送JSON数据. {"name":"zhangsan","pwd":"123456"}
     * 参数一：请求Url
     * 参数二：请求的JSON
     * 参数三：请求回调
     */
    public String postJsonParams(String url, String jsonParams) {
        String responseBody = "";
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
        Request request = new Request.Builder()
                .url(url)
                .addHeader("Accept", "application/json")
                .post(requestBody)
                .build();
        Response response = null;
        try {
            response = okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            logger.error("okhttp3 post 错误 >> ex = {}", ExceptionUtils.getStackTrace(e));
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return responseBody;
    }

    /**
     * Post请求发送JSON数据. {"name":"zhangsan","pwd":"123456"}
     * 参数一：请求Url
     * 参数二：请求的JSON
     * 参数三：请求回调
     */
    public String wechatPayPost(String url, String jsonParams, String token) {
        String responseBody = "";
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
        Request request = new Request.Builder()
                .url(url)
                .addHeader("Accept", "application/json")
                .addHeader("Authorization", token)
                .post(requestBody)
                .build();
        Response response = null;
        try {

            response = okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            logger.error("okhttp3 post 错误 >> ex = {}", ExceptionUtils.getStackTrace(e));
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return responseBody;
    }

    /**
     * Post请求发送xml数据....
     * 参数一：请求Url
     * 参数二：请求的xmlString
     * 参数三：请求回调
     */
    public String postXmlParams(String url, String xml) {
        String responseBody = "";
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml);
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        Response response = null;
        try {
            response = okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            logger.error("okhttp3 post 错误 >> ex = {}", ExceptionUtils.getStackTrace(e));
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return responseBody;
    }
}
